package com.tmt.im.wallet.config;

import com.tmt.im.wallet.config.beans.MyJwtAuthenticationConverter;
import com.tmt.im.wallet.service.IgniteService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import java.text.MessageFormat;

/**
 * @Description TODO
 * @Author wuyi
 * @Date 2024/7/17 16:53
 * @Version 1.0
 **/
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class ResourceServerConfig {

    private final String swaggerUiPath;

    private final String apiDocsPath;

    private final IgniteService igniteService;

    private final String apiUrlPrefix;

    public ResourceServerConfig(@Value("${api-url-prefix}")
                                String apiUrlPrefix,
                                @Value("${springdoc.swagger-ui.path}")
                                String swaggerUiPath,
                                @Value("${springdoc.api-docs.path}")
                                String apiDocsPath,
                                IgniteService igniteService) {
        this.apiUrlPrefix = apiUrlPrefix;
        this.apiDocsPath = apiDocsPath;
        this.swaggerUiPath = swaggerUiPath;
        this.igniteService = igniteService;
    }

    @Bean
    @Order(1)
    public SecurityFilterChain authorizationClientSecurityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests((authorize) -> authorize
                        .requestMatchers(
                                new AntPathRequestMatcher(swaggerUiPath.split("\\.")[0] + "**"),
                                new AntPathRequestMatcher(swaggerUiPath.split("\\.")[0] + "/**"),
                                new AntPathRequestMatcher(apiDocsPath.split("\\.")[0] + "**"),
                                new AntPathRequestMatcher(apiDocsPath.split("\\.")[0] + "/**"),
                                new AntPathRequestMatcher(MessageFormat.format("{0}/health/**", apiUrlPrefix)),
                                new AntPathRequestMatcher(MessageFormat.format("{0}/skin/show/**", apiUrlPrefix)),
                                new AntPathRequestMatcher(MessageFormat.format("{0}/recharge/confirm/sync", apiUrlPrefix)),
                                new AntPathRequestMatcher(MessageFormat.format("{0}/recharge/confirm/async", apiUrlPrefix)),
                                new AntPathRequestMatcher(MessageFormat.format("{0}/withdraw/confirm/async", apiUrlPrefix))
                        ).permitAll()
                        .anyRequest().authenticated())
                .oauth2ResourceServer((oauth2) -> oauth2
                        .jwt(c -> c.jwtAuthenticationConverter(new MyJwtAuthenticationConverter(igniteService)))
                )
        ;

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}
